// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright (c) 2021 Sartura */
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>


#define TARGET_NAME "spray"
#define TASK_COMM_LEN 0x10
#define ADDR 0x30000

//typedef void * function;
int if_hijack = 0;
int printk_flag = 0;
void * single_start = 0;
static __inline int handle_enter_write(struct bpf_raw_tracepoint_args *ctx);
static __inline int memcmp(const void* s1, const void* s2, size_t cnt){

  const char *t1 = s1;
  const char *t2 = s2;

  int res = 0;
  while(cnt-- > 0){
    if(*t1 > *t2){
      res =1;
      break;
    }
    else if(*t1 < *t2){
      res = -1;
      break;
    }
    else{
      t1++;
      t2++;
    }
  }

  return res;
}




SEC("kprobe/seq_open")
int BPF_KPROBE(seq_open,struct file *file, struct seq_operations *seq_operations)
{
	char comm[TASK_COMM_LEN];
    bpf_get_current_comm(&comm, sizeof(comm));
    if (memcmp(comm, TARGET_NAME, sizeof(TARGET_NAME))){
        return 0;
    }

	pid_t pid;
	const char *filename;
	pid = bpf_get_current_pid_tgid() >> 32;

	single_start = (void *)BPF_CORE_READ(seq_operations, start);
	//bpf_printk("0x%lx\n",single_start);
	//bpf_probe_write_user((char *)(AADR),single_start, sizeof(single_start));
	return 0;
}

SEC("raw_tracepoint/sys_enter")
int raw_tp_sys_enter(struct bpf_raw_tracepoint_args *ctx)
{
    unsigned long syscall_id = ctx->args[1];
    char comm[TASK_COMM_LEN];
    bpf_get_current_comm(&comm, sizeof(comm));
    if (memcmp(comm, TARGET_NAME, sizeof(TARGET_NAME))){
        return 0;
    }

    int pid = bpf_get_current_pid_tgid() & 0xffffffff;
    switch (syscall_id)
    {
        case 1:
            handle_enter_write(ctx);
            break;
        default:
            //bpf_printk("None of targets , break");
            return 0;
    }
    return 0;
}



static __inline int handle_enter_write(struct bpf_raw_tracepoint_args *ctx){

//   if(if_hijack == 1){
// 	  return 0;
//   }
  struct pt_regs *regs;
  char buf[0x40];
  char *pathname ;
  char *write_to = NULL;
  int len=0;
  int fd=0;
  regs = (struct pt_regs *)(ctx->args[0]);
  fd = PT_REGS_PARM1_CORE(regs);
  write_to = (char *)PT_REGS_PARM2_CORE(regs);
  
  len = PT_REGS_PARM3_CORE(regs);

  if((int)write_to == ADDR){
  bpf_probe_write_user((unsigned long *)ADDR,&single_start, sizeof(single_start));
  //bpf_printk("write address: %lx",write_to);
  }
  //if_hijack = 1;
  return 0;
}
char LICENSE[] SEC("license") = "Dual BSD/GPL";